﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.Linq;
using System.Windows;
using System.Windows.Data;
using System.Windows.Markup;

namespace EuroManager.Presentation.WebPortal.GameViewer.Utilities
{
    [ContentProperty("Options")]
    public class SelectConverter : IValueConverter
    {
        public SelectConverter()
            : this(new SelectOptionCollection())
        {
        }

        public SelectConverter(SelectOptionCollection cases)
        {
            Options = cases;
        }

        public SelectOptionCollection Options { get; private set; }

        public object Default { get; set; }

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null)
            {
                return Options.FirstOrDefault(x => x.For == null) ?? Default;
            }

            foreach (var o in Options.Where(x => x.For != null))
            {
                string str = value as string;
                string forString = o.For as string;

                if (str != null && forString != null)
                {
                    if (str == forString)
                    {
                        return o.Use;
                    }
                }

                object @for = o.For;

                if (TryConvert(culture, value, ref @for))
                {
                    if (value.Equals(@for))
                    {
                        return o.Use;
                    }
                }
            }

            return Default;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }

        private static bool TryConvert(CultureInfo culture, object value1, ref object value2)
        {
            Type type1 = value1.GetType();
            Type type2 = value2.GetType();

            if (type1 == type2)
            {
                return true;
            }

            if (type1.IsEnum)
            {
                value2 = Enum.Parse(type1, value2.ToString(), true);
                return true;
            }

            var convertible1 = value1 as IConvertible;
            var convertible2 = value2 as IConvertible;

            if (convertible1 != null && convertible2 != null)
            {
                value2 = System.Convert.ChangeType(value2, type1, culture);
                return true;
            }

            return false;
        }
    }
}
